package com.streamsets.datacollector.pileline.stage;

import com.streamsets.datacollector.model.jdbc.SourceJdbcConfigJson;
import com.streamsets.datacollector.pileline.enums.DbDriverEnum;
import com.streamsets.datacollector.pileline.enums.SourceConfigEnum;
import com.streamsets.datacollector.restapi.bean.ConfigConfigurationJson;
import com.streamsets.datacollector.restapi.bean.StageConfigurationJson;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 初始化数据库配置
 * @author wengzhonghui
 * @date 2019/10/16 19:12
 */
public class InitSourceDbConfig {

    /*
     * 数据源stage名称
     */
    public static final String STAGE_DB_SOURCE_NAME = "JDBCQueryConsumer_01";

    // 不同组件的驱动属性不一样，所以这个阶段定制一个
		public static final String DRIVER_CLASS_CONFIG_NAME = "hikariConfigBean.driverClassName";

    public static void init(StageConfigurationJson stage, SourceJdbcConfigJson sourceJdbcConfig){
        if(STAGE_DB_SOURCE_NAME.equalsIgnoreCase(stage.getInstanceName())) {
            if (sourceJdbcConfig != null) {
                List<ConfigConfigurationJson> configs = intConfig(stage.getConfiguration(), sourceJdbcConfig);
                stage.setConfiguration(configs);
            }
        }
    }

    public static List<ConfigConfigurationJson> intConfig(List<ConfigConfigurationJson> oldConfigs, SourceJdbcConfigJson sourceJdbcConfig){
        List<ConfigConfigurationJson> newConfigs = new ArrayList<>();
        for(ConfigConfigurationJson config :oldConfigs ){

            config = initOffsetColumn(config, sourceJdbcConfig);
            config = initIncrementalMode(config, sourceJdbcConfig);
            config = initQuery(config, sourceJdbcConfig);
            config = initialOffset(config, sourceJdbcConfig);

            config = initQueryInterval(config, sourceJdbcConfig);
            config = initConnectionString(config, sourceJdbcConfig);
            config = initUserName(config, sourceJdbcConfig);
            config = initPassword(config, sourceJdbcConfig);
            config = initDriverClassName(config, sourceJdbcConfig);

            newConfigs.add(config);
        }
        return newConfigs;
    }


    // 初始化是否增量采集属性
    private static ConfigConfigurationJson initIncrementalMode(ConfigConfigurationJson config, SourceJdbcConfigJson sourceJdbcConfig){
        if(SourceConfigEnum.isIncrementalMode.getName().equalsIgnoreCase(config.getName())){
            config = new ConfigConfigurationJson(SourceConfigEnum.isIncrementalMode.getName()
                    ,sourceJdbcConfig.getIsIncrementalModeBoolean());
        }
        if(sourceJdbcConfig.getIsIncrementalModeBoolean()){

        }
        return config;
    }



    // 初始化查询属性,包括全量和增量
    private static ConfigConfigurationJson initQuery(ConfigConfigurationJson config, SourceJdbcConfigJson sourceJdbcConfig){
        if(SourceConfigEnum.query.getName().equalsIgnoreCase(config.getName())){
            String tableName = getSourceTableName(sourceJdbcConfig);
            StringBuilder query = new StringBuilder();
            query.append("select * from  ");
            query.append(tableName);
            if(sourceJdbcConfig.getIsIncrementalModeBoolean()) {
                query.append(" where ")
                        .append(sourceJdbcConfig.getOffsetColumn())
                        .append("> ");
                if(sourceJdbcConfig.getOffsetColumnType() != null ){
                    if("date".equalsIgnoreCase(sourceJdbcConfig.getOffsetColumnType())){
                        if(DbDriverEnum.oracle.getName().equalsIgnoreCase(sourceJdbcConfig.getDriverClassName())){
                            query.append("to_date('${OFFSET}', 'yyyy-MM-dd HH24:mi:ss') ");
                        }else {
                            query.append("'${OFFSET}' ");
                        }
                    }else{
                        query.append(" ${OFFSET} ");
                    }
                }else{
                    query.append("'${OFFSET}' ");
                }

                query.append(" order by ")
                    .append(sourceJdbcConfig.getOffsetColumn())
                    .append(" asc ");
            }
            config = new ConfigConfigurationJson(SourceConfigEnum.query.getName()
                    ,query.toString());
        }
        return config;
    }



    // 初始化增量采集初始时间
    private static ConfigConfigurationJson initialOffset(ConfigConfigurationJson config, SourceJdbcConfigJson sourceJdbcConfig){
        if(SourceConfigEnum.initialOffset.getName().equalsIgnoreCase(config.getName())){
            String initialOffset = sourceJdbcConfig.getInitialOffset();
            initialOffset = StringUtils.isEmpty(initialOffset) ?  "1970-08-27 13:48:26" : initialOffset;
            config = new ConfigConfigurationJson(SourceConfigEnum.initialOffset.getName()
                    ,initialOffset);
        }
        return config;
    }

    // 初始化增量采集列
    private static ConfigConfigurationJson initOffsetColumn(ConfigConfigurationJson config, SourceJdbcConfigJson sourceJdbcConfig){
        if(SourceConfigEnum.offsetColumn.getName().equalsIgnoreCase(config.getName())){
            config = new ConfigConfigurationJson(SourceConfigEnum.offsetColumn.getName()
                    ,sourceJdbcConfig.getOffsetColumn());
            // 如果是全量，则把增量列设置为空
            if(sourceJdbcConfig.getIsIncrementalMode() == 0){
                config = new ConfigConfigurationJson(SourceConfigEnum.offsetColumn.getName()
                        ,"");
            }
        }
        return config;
    }

    // 初始化采集间隔时间
    private static ConfigConfigurationJson initQueryInterval(ConfigConfigurationJson config, SourceJdbcConfigJson sourceJdbcConfig){

        if(SourceConfigEnum.queryInterval.getName().equalsIgnoreCase(config.getName())){
            Integer queryInterval = sourceJdbcConfig.getQueryInterval();
            // 如果采集间隔时间为空，则默认为一天采集一次
            queryInterval = queryInterval == null ? 24*3600 : queryInterval;
            config = new ConfigConfigurationJson(SourceConfigEnum.queryInterval.getName()
                    ,"${"+queryInterval+"* SECONDS}");
        }
        return config;
    }


    // 初始化数据库连接
    private static ConfigConfigurationJson initConnectionString(ConfigConfigurationJson config, SourceJdbcConfigJson sourceJdbcConfig){

        if(SourceConfigEnum.jdbcConnectionString.getName().equalsIgnoreCase(config.getName())){
            config = new ConfigConfigurationJson(SourceConfigEnum.jdbcConnectionString.getName()
                    ,sourceJdbcConfig.getConnectionString());
        }
        return config;
    }

    // 初始化数据库用户名
    private static ConfigConfigurationJson initUserName(ConfigConfigurationJson config, SourceJdbcConfigJson sourceJdbcConfig){

        if(SourceConfigEnum.username.getName().equalsIgnoreCase(config.getName())){
            config = new ConfigConfigurationJson(SourceConfigEnum.username.getName()
                    ,sourceJdbcConfig.getJdbcUserName());
        }
        return config;
    }

    // 初始化数据库密码
    private static ConfigConfigurationJson initPassword(ConfigConfigurationJson config, SourceJdbcConfigJson sourceJdbcConfig){

        if(SourceConfigEnum.password.getName().equalsIgnoreCase(config.getName())){
            config = new ConfigConfigurationJson(SourceConfigEnum.password.getName()
                    ,sourceJdbcConfig.getJdbcPassword());
        }
        return config;
    }

    // 初始化数据库驱动
    private static ConfigConfigurationJson initDriverClassName(ConfigConfigurationJson config, SourceJdbcConfigJson sourceJdbcConfig){

        if(DRIVER_CLASS_CONFIG_NAME.equalsIgnoreCase(config.getName())){
            config = new ConfigConfigurationJson(DRIVER_CLASS_CONFIG_NAME
                    ,sourceJdbcConfig.getDriverClassName());
        }
        return config;
    }

    /*
     * 处理oracle创建表的时候，表名有大小写以""括住的场景,select * from "PERSON_tt3" 是正确的，select * from PERSON_tt3 会报错
     * @param [sourceJdbcConfig]
     * @return
     */
    private static String getSourceTableName(SourceJdbcConfigJson sourceJdbcConfig){
        String tableName = sourceJdbcConfig.getSourceTable();
        if(tableName!=null && sourceJdbcConfig.getDriverClassName() != null && sourceJdbcConfig.getDriverClassName().toLowerCase().contains("oracle")){
            tableName = "\"" + tableName +"\"";
        }
        return tableName;
    }

}
